From 803d748ac2955a89ccfb07e900b913f23fd55562 Mon Sep 17 00:00:00 2001 From: Nathan Froyd Date: Fri, 7 Apr 2017 12:32:42 -0400 Subject: [PATCH] add `overflow-checks` field to profiles ...and pass `-C overflow-checks` to the compiler when necessary. Fixes #2262. --- src/cargo/core/manifest.rs | 3 +++ src/cargo/ops/cargo_rustc/mod.rs | 29 ++++++++++++++++++++------ src/cargo/util/toml.rs | 5 ++++- tests/build.rs | 5 +++++ tests/test.rs | 35 ++++++++++++++++++++++++++++++++ 5 files changed, 70 insertions(+), 7 deletions(-) diff --git a/src/cargo/core/manifest.rs b/src/cargo/core/manifest.rs index ad9a129af..de18731de 100644 --- a/src/cargo/core/manifest.rs +++ b/src/cargo/core/manifest.rs @@ -145,6 +145,7 @@ pub struct Profile { pub rustdoc_args: Option>, pub debuginfo: Option, pub debug_assertions: bool, + pub overflow_checks: bool, #[serde(skip_serializing)] pub rpath: bool, pub test: bool, @@ -528,6 +529,7 @@ impl Profile { Profile { debuginfo: Some(2), debug_assertions: true, + overflow_checks: true, ..Profile::default() } } @@ -594,6 +596,7 @@ impl Default for Profile { rustdoc_args: None, debuginfo: None, debug_assertions: false, + overflow_checks: false, rpath: false, test: false, doc: false, diff --git a/src/cargo/ops/cargo_rustc/mod.rs b/src/cargo/ops/cargo_rustc/mod.rs index 6ba1c8c88..b20f5709b 100644 --- a/src/cargo/ops/cargo_rustc/mod.rs +++ b/src/cargo/ops/cargo_rustc/mod.rs @@ -597,8 +597,8 @@ fn build_base_args(cx: &mut Context, crate_types: &[&str]) { let Profile { ref opt_level, lto, codegen_units, ref rustc_args, debuginfo, - debug_assertions, rpath, test, doc: _doc, run_custom_build, - ref panic, rustdoc_args: _, check, + debug_assertions, overflow_checks, rpath, test, doc: _doc, + run_custom_build, ref panic, rustdoc_args: _, check, } = *unit.profile; assert!(!run_custom_build); @@ -678,10 +678,27 @@ fn build_base_args(cx: &mut Context, cmd.args(args); } - if debug_assertions && opt_level != "0" { - cmd.args(&["-C", "debug-assertions=on"]); - } else if !debug_assertions && opt_level == "0" { - cmd.args(&["-C", "debug-assertions=off"]); + // -C overflow-checks is implied by the setting of -C debug-assertions, + // so we only need to provide -C overflow-checks if it differs from + // the value of -C debug-assertions we would provide. + if opt_level != "0" { + if debug_assertions { + cmd.args(&["-C", "debug-assertions=on"]); + if !overflow_checks { + cmd.args(&["-C", "overflow-checks=off"]); + } + } else if overflow_checks { + cmd.args(&["-C", "overflow-checks=on"]); + } + } else { + if !debug_assertions { + cmd.args(&["-C", "debug-assertions=off"]); + if overflow_checks { + cmd.args(&["-C", "overflow-checks=on"]); + } + } else if !overflow_checks { + cmd.args(&["-C", "overflow-checks=off"]); + } } if test && unit.target.harness() { diff --git a/src/cargo/util/toml.rs b/src/cargo/util/toml.rs index 990a7d856..084e2359b 100644 --- a/src/cargo/util/toml.rs +++ b/src/cargo/util/toml.rs @@ -371,6 +371,8 @@ pub struct TomlProfile { debug_assertions: Option, rpath: Option, panic: Option, + #[serde(rename = "overflow-checks")] + overflow_checks: Option, } #[derive(Clone, Debug)] @@ -1469,7 +1471,7 @@ fn build_profiles(profiles: &Option) -> Profiles { fn merge(profile: Profile, toml: Option<&TomlProfile>) -> Profile { let &TomlProfile { ref opt_level, lto, codegen_units, ref debug, debug_assertions, rpath, - ref panic + ref panic, ref overflow_checks, } = match toml { Some(toml) => toml, None => return profile, @@ -1488,6 +1490,7 @@ fn build_profiles(profiles: &Option) -> Profiles { rustdoc_args: None, debuginfo: debug.unwrap_or(profile.debuginfo), debug_assertions: debug_assertions.unwrap_or(profile.debug_assertions), + overflow_checks: overflow_checks.unwrap_or(profile.overflow_checks), rpath: rpath.unwrap_or(profile.rpath), test: profile.test, doc: profile.doc, diff --git a/tests/build.rs b/tests/build.rs index 1eea86b5c..3839d1bbd 100644 --- a/tests/build.rs +++ b/tests/build.rs @@ -2535,6 +2535,7 @@ fn compiler_json_error_format() { "debug_assertions": true, "debuginfo": 2, "opt_level": "0", + "overflow_checks": true, "test": false }, "features": [], @@ -2574,6 +2575,7 @@ fn compiler_json_error_format() { "debug_assertions": true, "debuginfo": 2, "opt_level": "0", + "overflow_checks": true, "test": false }, "features": [], @@ -2593,6 +2595,7 @@ fn compiler_json_error_format() { "debug_assertions": true, "debuginfo": 2, "opt_level": "0", + "overflow_checks": true, "test": false }, "features": [], @@ -2620,6 +2623,7 @@ fn compiler_json_error_format() { "debug_assertions": true, "debuginfo": 2, "opt_level": "0", + "overflow_checks": true, "test": false }, "features": [], @@ -2679,6 +2683,7 @@ fn message_format_json_forward_stderr() { "debug_assertions":true, "debuginfo":2, "opt_level":"0", + "overflow_checks": true, "test":false }, "features":[], diff --git a/tests/test.rs b/tests/test.rs index f55c0bc98..895026d44 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -117,6 +117,41 @@ test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured ")); } +#[test] +fn cargo_test_overflow_checks() { + if !is_nightly() { + return; + } + let p = project("foo") + .file("Cargo.toml", r#" + [package] + name = "foo" + version = "0.5.0" + authors = [] + + [[bin]] + name = "foo" + + [profile.release] + overflow-checks = true + "#) + .file("src/foo.rs", r#" + use std::panic; + pub fn main() { + let r = panic::catch_unwind(|| { + [1, i32::max_value()].iter().sum::(); + }); + assert!(r.is_err()); + }"#); + + assert_that(p.cargo_process("build").arg("--release"), + execs().with_status(0)); + assert_that(&p.release_bin("foo"), existing_file()); + + assert_that(process(&p.release_bin("foo")), + execs().with_status(0).with_stdout("")); +} + #[test] fn cargo_test_verbose() { let p = project("foo") -- 2.30.2